#include "hd.h"
#include <avr/interrupt.h>
/************************************************

                    spi

*************************************************/
uint8_t Buffer[] = {10,11,12,13,14};
uint8_t TX_ADDRESS[TX_ADR_WIDTH]  = {0x34,0x43,0x10,0x10,0x01}; // Define a static TX address
uint8_t Local_ADDRESS[TX_ADR_WIDTH]  = {0x34,0x43,0x10,0x10,0x02}; // Define a static Local address

/**************************************************
Function: SPI_RW();

Description:
  Writes one byte to nRF24L01, and return the byte read
  from nRF24L01 during write, according to SPI protocol  */
/**************************************************/
unsigned char SPI_RW(unsigned char byte)
{
	unsigned char  bit_ctr;
	cli();
   	for(bit_ctr=0;bit_ctr<8;bit_ctr++)   	// output 8-bit
   	{
   		if(byte & 0x80)
   		{
   		    MOSI_on;
   		}
        else
        {
            MOSI_off;
        }
   		byte=(byte<<1);           		// shift next bit into MSB..
   		MSCK_on;                  // Set nRF24L01_SCK high..
   		byte|=MISO_s;
   		MSCK_off;            		// ..then set nRF24L01_SCK low again
   	}
   	sei();
    return(byte);           		  		// return read byte
}
/**************************************************
Function: SPI_RW_Reg();

Description:
  Writes value 'value' to register 'reg' */
/**************************************************/
unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)
{
	unsigned char status;
//	DI();
	CSN_off;          // nRF24L01_CSN low, init SPI transaction.
	status=SPI_RW(reg);      // select register
  	SPI_RW(value);             // ..and write value to it..
  	CSN_on;                   // nRF24L01_CSN high again
//  EI();
  	return(status);            // return nRF24L01 status byte
}
/**************************************************
Function: SPI_Read();

Description:
  Read one byte from nRF24L01 register, 'reg'  */
/**************************************************/
unsigned char SPI_Read(unsigned char reg)
{
	unsigned char reg_val;
//	DI();
	CSN_off;       	// nRF24L01_CSN low, initialize SPI communication...
  	SPI_RW(reg);            // Select register to read from..
  	reg_val = SPI_RW(0);    // ..then read registervalue
    CSN_on;       	// nRF24L01_CSN high, terminate SPI communication
 // 	EI();
  	return(reg_val);        // return register value
}
/**************************************************
Function: SPI_Read_Buf();

Description:
  Reads 'bytes' #of bytes from register 'reg'
  Typically used to read RX payload, Rx/Tx address */
/**************************************************/
unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
{
	unsigned char status,byte_ctr;
//	DI();
	CSN_off;                   // Set nRF24L01_CSN low, init SPI tranaction
  	status = SPI_RW(reg);       		// Select register to write to and read status byte
	for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
    	pBuf[byte_ctr] = SPI_RW(0);    // Perform SPI_RW to read byte from nRF24L01
	CSN_on;                 // Set nRF24L01_CSN high again
//  EI();
  	return(status);                    // return nRF24L01 status byte
}
/**************************************************
Function: SPI_Write_Buf();

Description:
  Writes contents of buffer '*pBuf' to nRF24L01
  Typically used to write TX payload, Rx/Tx address */
/**************************************************/
unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
{
	unsigned char status,byte_ctr;
//	DI();
	CSN_off;                    		// Set nRF24L01_CSN low, init SPI tranaction
  	status = SPI_RW(reg);  // Select register to write to and read status byte
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	for(byte_ctr=0; byte_ctr<bytes; byte_ctr++)// then write all byte in buffer(*pBuf)
  	{
  	    SPI_RW(*pBuf++);
  	}
	CSN_on;                           // Set nRF24L01_CSN high again
//  	EI();
  	return(status);          					// return nRF24L01 status byte
}
/**************************************************
Function: RX_Mode();

Description:
  This function initializes one nRF24L01 device to
  RX Mode, set RX address, writes RX payload width,
  select RF channel, datarate & LNA HCURR.
  After init, CE is toggled high, which means that
  this device is now ready to receive a datapacket. */
/**************************************************/
void RX_Mode(void)
{
	CE_off;
//	DI();
  	SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, Local_ADDRESS, TX_ADR_WIDTH); // Use the same address on the RX device as the TX device

  	SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      // Enable Auto.Ack:Pipe0
  	SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // Enable Pipe0
  	SPI_RW_Reg(WRITE_REG + RF_CH, 40);        // Select RF channel 40
  	SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // Select same RX payload width as TX Payload width
  	SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR
  	SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);     // Set PWR_UP bit, enable CRC(2 bytes) & Prim:RX. RX_DR enabled..
//	EI();
  	CE_on;
	//  This device is now ready to receive one packet of 16 bytes payload from a TX device sending to address
  //  '3443101001', with auto acknowledgment, retransmit count of 10, RF channel 40 and datarate = 2Mbps.

}
/**************************************************/

/**************************************************
Function: TX_Mode();

Description:
  This function initializes one nRF24L01 device to
  TX mode, set TX address, set RX address for auto.ack,
  fill TX payload, select RF channel, datarate & TX pwr.
  PWR_UP is set, CRC(2 bytes) is enabled, & PRIM:TX.

  ToDo: One high pulse(>10us) on CE will now send this
  packet and expext an acknowledgment from the RX device. */
/**************************************************/
void TX_Mode(void)
{
	CE_off;
//	DI();
  	SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // Writes TX_Address to nRF24L01
  	SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack
  	SPI_Write_Buf(WR_TX_PLOAD, Buffer, TX_PLOAD_WIDTH); // Writes data to TX payload

  	SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      // Enable Auto.Ack:Pipe0
  	SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // Enable Pipe0
  	SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...
  	SPI_RW_Reg(WRITE_REG + RF_CH, 40);        // Select RF channel 40
  	SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR
  	SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);     // Set PWR_UP bit, enable CRC(2 bytes) & Prim:TX. MAX_RT & TX_DS enabled..
//	EI();
	CE_on;
    asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
  	asm("nop");
}
uint8_t i=0;
uint8_t j=0;
/*void rf(void)
{
    RX_Mode();
    if(!IRQ_s)
    {
        if(SPI_Read(STATUS)&RX_DR)
        {
  //          SPI_Read_Buf(RD_RX_PLOAD,Buffer,TX_PLOAD_WIDTH);
            Buffer[0]=0x20;
            SPI_RW_Reg(WRITE_REG+STATUS,0xff);
        }
   //     Buffer[0]=IRQ_s;
     //   Buffer[0]=SPI_Read(STATUS);
    //    SPI_Read_Buf(RD_RX_PLOAD,Buffer,TX_PLOAD_WIDTH);
        if(!(IRQ_s))
        {
            SPI_Read_Buf(RD_RX_PLOAD,Buffer,TX_PLOAD_WIDTH);
    //        Buffer[0]=SPI_Read(STATUS);
     //       Buffer[0]=20;
            SPI_RW_Reg(WRITE_REG+STATUS,0x40);
            j=1;
        }
        else
        {
 //           Buffer[0]=SPI_Read(STATUS);
        }

        display_clear();
        turn_add(Buffer[i]);
        if(j==1)
        {
            i++;
            if(i==5)
            {
                i=0;
                j=0;
                Buffer[0]=SPI_Read(STATUS);
            }
        }
  //  }
}*/

void rf(void)
{
    TX_Mode();
    if(!(IRQ_s))
    {
        SPI_RW_Reg(WRITE_REG+STATUS,0xff);
        SPI_RW_Reg(FLUSH_TX,0);
        Buffer[0]+=1;
        Buffer[1]+=1;
        Buffer[2]+=1;
        Buffer[3]+=1;
        Buffer[4]+=1;
    }
 /*   if(!IRQ_s)
    {
        if(SPI_Read(STATUS)&RX_DR)
        {
  //          SPI_Read_Buf(RD_RX_PLOAD,Buffer,TX_PLOAD_WIDTH);
            Buffer[0]=0x20;
            SPI_RW_Reg(WRITE_REG+STATUS,0xff);
        }*/
   //     Buffer[0]=IRQ_s;
     //   Buffer[0]=SPI_Read(STATUS);
    //    SPI_Read_Buf(RD_RX_PLOAD,Buffer,TX_PLOAD_WIDTH);
 /*       if(!(IRQ_s))
        {
            SPI_Read_Buf(RD_RX_PLOAD,Buffer,TX_PLOAD_WIDTH);
    //        Buffer[0]=SPI_Read(STATUS);
     //       Buffer[0]=20;
            SPI_RW_Reg(WRITE_REG+STATUS,0x40);
            j=1;
        }
        else
        {
 //           Buffer[0]=SPI_Read(STATUS);
        }

        display_clear();
        turn_add(Buffer[i]);
        if(j==1)
        {
            i++;
            if(i==5)
            {
                i=0;
                j=0;
                Buffer[0]=SPI_Read(STATUS);
            }
        }*/
  //  }
}
